from flask import Blueprint, request, jsonify, session
from extensions import db
from models import User, UserRole
from auth import (
    generate_token, login_required, admin_required,
    validate_user_input, check_user_exists
)
from database import get_user_stats
from datetime import datetime
import logging

# 创建认证蓝图
auth_bp = Blueprint('auth', __name__, url_prefix='/api/auth')
logger = logging.getLogger('biomni_app')

@auth_bp.route('/register', methods=['POST'])
def register():
    """用户注册"""
    try:
        data = request.get_json()
        username = data.get('username', '').strip()
        email = data.get('email', '').strip().lower()
        password = data.get('password', '')
        
        logger.info(f"用户注册请求: {username}, {email}")
        
        # 验证输入
        validation_errors = validate_user_input(username, email, password)
        if validation_errors:
            return jsonify({
                'success': False,
                'message': '输入验证失败',
                'errors': validation_errors
            }), 400
        
        # 检查用户是否已存在
        exists, error_message = check_user_exists(username=username, email=email)
        if exists:
            return jsonify({
                'success': False,
                'message': error_message
            }), 409
        
        # 创建新用户
        new_user = User(
            username=username,
            email=email,
            role=UserRole.USER,
            balance=10.0,  # 新用户赠送10美元
            weekly_request_limit=50,  # 新用户每周50次请求
            is_active=True,
            is_verified=False  # 需要邮箱验证（暂时跳过）
        )
        new_user.set_password(password)
        
        db.session.add(new_user)
        db.session.commit()
        
        logger.info(f"用户注册成功: {username} (ID: {new_user.id})")
        
        # 自动登录
        session['user_id'] = new_user.id
        session['username'] = new_user.username
        
        # 生成JWT token
        token = generate_token(new_user.id)
        
        return jsonify({
            'success': True,
            'message': '注册成功',
            'user': new_user.to_dict(),
            'token': token
        }), 201
        
    except Exception as e:
        db.session.rollback()
        logger.error(f"用户注册失败: {str(e)}", exc_info=True)
        return jsonify({
            'success': False,
            'message': f'注册失败: {str(e)}'
        }), 500

@auth_bp.route('/login', methods=['POST'])
def login():
    """用户登录"""
    try:
        data = request.get_json()
        username_or_email = data.get('username', '').strip()
        password = data.get('password', '')
        
        logger.info(f"用户登录请求: {username_or_email}")
        
        if not username_or_email or not password:
            return jsonify({
                'success': False,
                'message': '用户名和密码不能为空'
            }), 400
        
        # 查找用户（支持用户名或邮箱登录）
        user = User.query.filter(
            (User.username == username_or_email) | 
            (User.email == username_or_email.lower())
        ).first()
        
        if not user or not user.check_password(password):
            logger.warning(f"登录失败: 用户名或密码错误 - {username_or_email}")
            return jsonify({
                'success': False,
                'message': '用户名或密码错误'
            }), 401
        
        if not user.is_active:
            logger.warning(f"登录失败: 账户已被禁用 - {username_or_email}")
            return jsonify({
                'success': False,
                'message': '账户已被禁用，请联系管理员'
            }), 401
        
        # 更新最后登录时间
        user.last_login = datetime.utcnow()
        db.session.commit()
        
        # 设置session
        session['user_id'] = user.id
        session['username'] = user.username
        
        # 生成JWT token
        token = generate_token(user.id)
        
        logger.info(f"用户登录成功: {user.username} (ID: {user.id})")
        
        return jsonify({
            'success': True,
            'message': '登录成功',
            'user': user.to_dict(),
            'token': token
        })
        
    except Exception as e:
        logger.error(f"用户登录失败: {str(e)}", exc_info=True)
        return jsonify({
            'success': False,
            'message': f'登录失败: {str(e)}'
        }), 500

@auth_bp.route('/logout', methods=['POST'])
@login_required
def logout():
    """用户登出"""
    try:
        username = session.get('username', 'Unknown')
        logger.info(f"用户登出: {username}")
        
        # 清除session
        session.clear()
        
        return jsonify({
            'success': True,
            'message': '登出成功'
        })
        
    except Exception as e:
        logger.error(f"用户登出失败: {str(e)}", exc_info=True)
        return jsonify({
            'success': False,
            'message': f'登出失败: {str(e)}'
        }), 500

@auth_bp.route('/profile', methods=['GET'])
@login_required
def get_profile():
    """获取用户资料"""
    try:
        from flask import g
        user = g.current_user
        
        # 获取用户统计信息
        user_stats = get_user_stats(user.id)
        
        return jsonify({
            'success': True,
            'data': user_stats
        })
        
    except Exception as e:
        logger.error(f"获取用户资料失败: {str(e)}", exc_info=True)
        return jsonify({
            'success': False,
            'message': f'获取用户资料失败: {str(e)}'
        }), 500

@auth_bp.route('/profile', methods=['PUT'])
@login_required
def update_profile():
    """更新用户资料"""
    try:
        from flask import g
        user = g.current_user
        data = request.get_json()
        
        # 可更新的字段
        username = data.get('username', '').strip()
        email = data.get('email', '').strip().lower()
        current_password = data.get('current_password', '')
        new_password = data.get('new_password', '')
        
        updated_fields = []
        
        # 更新用户名
        if username and username != user.username:
            validation_errors = validate_user_input(username=username)
            if validation_errors:
                return jsonify({
                    'success': False,
                    'message': '用户名验证失败',
                    'errors': validation_errors
                }), 400
            
            exists, error_message = check_user_exists(username=username, exclude_user_id=user.id)
            if exists:
                return jsonify({
                    'success': False,
                    'message': error_message
                }), 409
            
            user.username = username
            updated_fields.append('用户名')
        
        # 更新邮箱
        if email and email != user.email:
            validation_errors = validate_user_input(email=email)
            if validation_errors:
                return jsonify({
                    'success': False,
                    'message': '邮箱验证失败',
                    'errors': validation_errors
                }), 400
            
            exists, error_message = check_user_exists(email=email, exclude_user_id=user.id)
            if exists:
                return jsonify({
                    'success': False,
                    'message': error_message
                }), 409
            
            user.email = email
            user.is_verified = False  # 需要重新验证邮箱
            updated_fields.append('邮箱')
        
        # 更新密码
        if new_password:
            if not current_password:
                return jsonify({
                    'success': False,
                    'message': '请输入当前密码'
                }), 400
            
            if not user.check_password(current_password):
                return jsonify({
                    'success': False,
                    'message': '当前密码错误'
                }), 400
            
            validation_errors = validate_user_input(password=new_password)
            if validation_errors:
                return jsonify({
                    'success': False,
                    'message': '新密码验证失败',
                    'errors': validation_errors
                }), 400
            
            user.set_password(new_password)
            updated_fields.append('密码')
        
        if updated_fields:
            user.updated_at = datetime.utcnow()
            db.session.commit()
            
            logger.info(f"用户资料更新成功: {user.username} - {', '.join(updated_fields)}")
            
            return jsonify({
                'success': True,
                'message': f'成功更新: {", ".join(updated_fields)}',
                'user': user.to_dict()
            })
        else:
            return jsonify({
                'success': True,
                'message': '没有需要更新的内容',
                'user': user.to_dict()
            })
        
    except Exception as e:
        db.session.rollback()
        logger.error(f"更新用户资料失败: {str(e)}", exc_info=True)
        return jsonify({
            'success': False,
            'message': f'更新失败: {str(e)}'
        }), 500

@auth_bp.route('/change-password', methods=['POST'])
@login_required
def change_password():
    """修改密码"""
    try:
        from flask import g
        user = g.current_user
        data = request.get_json()
        
        current_password = data.get('current_password', '')
        new_password = data.get('new_password', '')
        
        if not current_password or not new_password:
            return jsonify({
                'success': False,
                'message': '当前密码和新密码不能为空'
            }), 400
        
        if not user.check_password(current_password):
            return jsonify({
                'success': False,
                'message': '当前密码错误'
            }), 400
        
        validation_errors = validate_user_input(password=new_password)
        if validation_errors:
            return jsonify({
                'success': False,
                'message': '新密码验证失败',
                'errors': validation_errors
            }), 400
        
        user.set_password(new_password)
        user.updated_at = datetime.utcnow()
        db.session.commit()
        
        logger.info(f"用户密码修改成功: {user.username}")
        
        return jsonify({
            'success': True,
            'message': '密码修改成功'
        })
        
    except Exception as e:
        db.session.rollback()
        logger.error(f"修改密码失败: {str(e)}", exc_info=True)
        return jsonify({
            'success': False,
            'message': f'修改密码失败: {str(e)}'
        }), 500

@auth_bp.route('/check', methods=['GET'])
def check_auth():
    """检查认证状态"""
    try:
        user_id = session.get('user_id')
        
        if not user_id:
            return jsonify({
                'success': False,
                'authenticated': False,
                'message': '未登录'
            })
        
        user = User.query.get(user_id)
        if not user or not user.is_active:
            session.clear()
            return jsonify({
                'success': False,
                'authenticated': False,
                'message': '用户不存在或已被禁用'
            })
        
        return jsonify({
            'success': True,
            'authenticated': True,
            'user': user.to_dict()
        })
        
    except Exception as e:
        logger.error(f"检查认证状态失败: {str(e)}", exc_info=True)
        return jsonify({
            'success': False,
            'authenticated': False,
            'message': f'检查认证状态失败: {str(e)}'
        }), 500

@auth_bp.route('/status', methods=['GET'])
def auth_status():
    """获取认证状态（支持JWT Token）"""
    try:
        # 检查Authorization header中的JWT token
        auth_header = request.headers.get('Authorization')
        if auth_header and auth_header.startswith('Bearer '):
            token = auth_header.split(' ')[1]
            try:
                import jwt
                from auth import JWT_SECRET_KEY, JWT_ALGORITHM
                payload = jwt.decode(token, JWT_SECRET_KEY, algorithms=[JWT_ALGORITHM])
                user_id = payload.get('user_id')
                
                if user_id:
                    user = User.query.get(user_id)
                    if user and user.is_active:
                        return jsonify({
                            'success': True,
                            'authenticated': True,
                            'user': user.to_dict()
                        })
            except jwt.ExpiredSignatureError:
                return jsonify({
                    'success': False,
                    'authenticated': False,
                    'message': 'Token已过期'
                }), 401
            except jwt.InvalidTokenError:
                return jsonify({
                    'success': False,
                    'authenticated': False,
                    'message': 'Token无效'
                }), 401
        
        # 检查session
        user_id = session.get('user_id')
        if user_id:
            user = User.query.get(user_id)
            if user and user.is_active:
                return jsonify({
                    'success': True,
                    'authenticated': True,
                    'user': user.to_dict()
                })
        
        return jsonify({
            'success': False,
            'authenticated': False,
            'message': '未登录'
        })
        
    except Exception as e:
        logger.error(f"获取认证状态失败: {str(e)}", exc_info=True)
        return jsonify({
            'success': False,
            'authenticated': False,
            'message': f'获取认证状态失败: {str(e)}'
        }), 500

# 管理员相关路由
@auth_bp.route('/admin/users', methods=['GET'])
@admin_required
def list_users():
    """获取用户列表（管理员）"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 20, type=int)
        search = request.args.get('search', '').strip()
        
        query = User.query
        
        if search:
            query = query.filter(
                (User.username.contains(search)) |
                (User.email.contains(search))
            )
        
        pagination = query.paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        users_data = [user.to_dict() for user in pagination.items]
        
        return jsonify({
            'success': True,
            'data': {
                'users': users_data,
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total': pagination.total,
                    'pages': pagination.pages,
                    'has_prev': pagination.has_prev,
                    'has_next': pagination.has_next
                }
            }
        })
        
    except Exception as e:
        logger.error(f"获取用户列表失败: {str(e)}", exc_info=True)
        return jsonify({
            'success': False,
            'message': f'获取用户列表失败: {str(e)}'
        }), 500

@auth_bp.route('/admin/users/<int:user_id>/toggle-status', methods=['POST'])
@admin_required
def toggle_user_status(user_id):
    """切换用户状态（管理员）"""
    try:
        from flask import g
        admin_user = g.current_user
        
        user = User.query.get(user_id)
        if not user:
            return jsonify({
                'success': False,
                'message': '用户不存在'
            }), 404
        
        if user.id == admin_user.id:
            return jsonify({
                'success': False,
                'message': '不能禁用自己的账户'
            }), 400
        
        user.is_active = not user.is_active
        user.updated_at = datetime.utcnow()
        db.session.commit()
        
        status = '启用' if user.is_active else '禁用'
        logger.info(f"管理员 {admin_user.username} {status}了用户 {user.username}")
        
        return jsonify({
            'success': True,
            'message': f'用户已{status}',
            'user': user.to_dict()
        })
        
    except Exception as e:
        db.session.rollback()
        logger.error(f"切换用户状态失败: {str(e)}", exc_info=True)
        return jsonify({
            'success': False,
            'message': f'操作失败: {str(e)}'
        }), 500